package connection {
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;

import geditor.common.AbstractDrawComponent;
import geditor.common.DrawComponent;

import mx.containers.Canvas;

/**
 * This component represents link between two components (they must implement Connectable interface)
 */
public class ConnectionComponent extends AbstractDrawComponent implements DrawComponent {
    /**
     * Start of the connection
     */
    private var _start:ConnectionPoint;

    /**
     * End of the connection
     */
    private var _end:ConnectionPoint;

    private var _startDrawPoint:ConnectionDrawPoint;
    private var _endDrawPoint:ConnectionDrawPoint;

    public function get start():ConnectionPoint {
        return _start;
    }

    public function get end():ConnectionPoint {
        return _end;
    }

    public function set start(value:ConnectionPoint):void {
        var changed:Boolean = false;
        if (_start != value) {
            changed = true;

            if (_start != null)
                _start.removeEventListener("change", _pointChangeStart);
        }

        _start = value;
        if (changed && _start != null) {
            _start.addEventListener("change", _pointChangeStart);
        }

        fireChange();
    }

    public function set end(value:ConnectionPoint):void {
        var changed:Boolean = false;
        if (_end != value) {
            changed = true;

            if (_end != null)
                _end.removeEventListener("change", _pointChangeEnd);
        }

        _end = value;
        if (changed && _end != null) {
            _end.addEventListener("change", _pointChangeEnd);
        }

        fireChange();
    }

    private function _pointChangeStart(evt:Event):void {
        refresh();
        fireChange();
    }

    private function _pointChangeEnd(evt:Event):void {
        refresh();
        fireChange();
    }

    public function ConnectionComponent() {
        _startDrawPoint = new ConnectionDrawPoint(this, true);
        _endDrawPoint = new ConnectionDrawPoint(this, false);

        addEventListener("load", _load);
    }

    private function _load(evt:Event):void {
        if (_start == null && _end == null) {
            startCreating();
        }
    }

    private function startCreating():void {
        tool.startAlign(_startDrawPoint);

        var downListener:Function = function(evt:MouseEvent):void {
            tool.removeEventListener("mouseDown", downListener);
            //когда пользователь поставил первую точку

            if (tool.currentAlignObject != null) {
                //ждем, когда пользователь поставил вторую точку
                var upListener:Function = function(evt:MouseEvent):void {
                    tool.panEnabled = true;
                    tool.removeEventListener("mouseUp", upListener);

                    if (tool.currentAlignObject != null) {
                        //todo проверить та же ли это точка или нет?
                        _endDrawPoint.doAlign(tool.currentAlignObject);
                        tool.finishCreating(true);
                    } else {
                        tool.finishCreating(false);
                    }
                };

                tool.addEventListener("mouseUp", upListener);

                _startDrawPoint.doAlign(tool.currentAlignObject);
                tool.stopAlign();
                tool.startAlign(_endDrawPoint);
                tool.panEnabled = false;
            } else {
                tool.finishCreating(false);
            }
        };

        tool.addEventListener("mouseDown", downListener);
    }

    override public function refresh():void {
        if (_start != null && _end != null) {
            g.clear();

            var startPoint:Point = _start.point;
            var endPoint:Point = _end.point;

            g.lineStyle(1, 0x000000);
            g.moveTo(startPoint.x, startPoint.y);
            g.lineTo(endPoint.x, endPoint.y);
        }
    }

    private var _display:Canvas = new Canvas();
    private var g:Graphics = _display.graphics;

    public function get scalableDisplay():DisplayObject {
        return _display;
    }

    public function get notScalableDisplay():DisplayObject {
        return null;
    }

    public function get zIndex():int {
        return 0;
    }
}
}